﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using Transferomatic.Enumerators;
using Transferomatic.Views;
using System.IO;

namespace Transferomatic.ApplicationControllers
{
    public partial class Controller : IDisposable
    {
        #region Members
        private Object _LockObject = new Object();
        private int _ActiveTransferCount;
        #endregion

        #region Properties
        public int ActiveTransferCount
        {
            get
            {
                lock (this._LockObject)
                {
                    int theActiveTransferCount = 0;

                    for (int i = 0; i < this._MainView.gridTransfers.Rows.Count; i++)
                    {
                        TransferAgent thisAgent =
                            this._MainView.gridTransfers.Rows[i].Tag as
                                TransferAgent;

                        if (null != thisAgent)
                        {
                            if (thisAgent.Status.Equals(TransferAgentStatus.Transferring))
                            {
                                ++theActiveTransferCount;
                            }
                        }
                    }

                    return theActiveTransferCount;
                }
            }
        }
        #endregion

        #region Methods
        public bool StartTransfer(TransferAgent theAgent)
        {
            if (null != theAgent)
            {
                lock (this._LockObject)
                {
                    if (this._ActiveTransferCount < RegistryAgent.ConcurrentDownloads &&
                        theAgent.Status.Equals(TransferAgentStatus.NotStarted))
                    {
                        Thread thisThread = new Thread(new ThreadStart(theAgent.Start));
                        thisThread.Name = theAgent.GetHashCode().ToString(
                            CultureInfo.CurrentCulture);

                        Controller.Threads.Add(thisThread);

                        ++this._ActiveTransferCount;

                        thisThread.Start();
                        return true;
                    }
                }
            }
            return false;
        }
        
        #region Event Handlers
        private void TransferAgent_StatusChanged(
            object sender,
            EventArgs e)
        {
            Application.DoEvents();

            TransferAgent theInstance = sender as TransferAgent;

            for (int i = 0; i < this._MainView.gridTransfers.Rows.Count; i++)
            {
                if (this._MainView.gridTransfers.Rows[i].Tag.Equals(theInstance))
                {
                    switch (theInstance.Status)
                    {
                        case TransferAgentStatus.Transferring:
                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_CURRENT_FILE].Value =
                                String.Format(
                                    CultureInfo.CurrentCulture,
                                    "{0} - {1}Mb",
                                    theInstance.CurrentFile.Name,
                                    Math.Round((decimal)theInstance.CurrentFile.Length / 1048576, 2));

                            Application.DoEvents();

                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_PROGRESS].Value =
                                String.Format(
                                    CultureInfo.CurrentCulture,
                                    "{0}%",
                                    theInstance.TransferredPercentage);

                            Application.DoEvents();

                            double theRed = theInstance.TransferredPercentage < 50
                                ? 255
                                : 255 - (255.0 / 100 * ((theInstance.TransferredPercentage - 50) * 2));
                            double theGreen = theInstance.TransferredPercentage < 50
                                ? 255.0 / 100 * (theInstance.TransferredPercentage * 2)
                                : 255;

                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_PROGRESS].Style.BackColor =
                                Color.FromArgb((byte)theRed, (byte)theGreen, 0);

                            Application.DoEvents();

                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_STATUS].Value =
                                String.Format(
                                    CultureInfo.CurrentCulture,
                                    "{0}Mb Remaining",
                                    theInstance.RemainingAmount);

                            Application.DoEvents();
                            break;
                        case TransferAgentStatus.Paused:
                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_STATUS].Value =
                                "Paused";
                            break;
                        case TransferAgentStatus.Cancelled:
                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_STATUS].Value =
                                "Cancelled"; 
                            break;
                        case TransferAgentStatus.Failed:
                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_STATUS].Value =
                                String.Format(
                                    CultureInfo.CurrentCulture,
                                    "Failed - {0}",
                                    theInstance.StatusMessage);
                            break;
                        default:
                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_PROGRESS].Value = 
                                "0%";

                            this._MainView.gridTransfers.Rows[i].Cells[MainView.COLUMN_INDEX_STATUS].Value =
                                theInstance.StatusMessage;
                            break;
                    }
                    break;
                }
            }
        }

        private void TransferAgent_Transferring(
            object sender,
            EventArgs e)
        {
            this.UpdateStatusBar();
        }

        private void TransferAgent_Paused(
            object sender,
            EventArgs e)
        {
            TransferAgent theInstance =
                sender as TransferAgent;

            Controller.AbortAndRemoveThread(theInstance);

            lock (this._LockObject)
            {
                --this._ActiveTransferCount;
            } 
            
            this.UpdateStatusBar();
        }

        private void TransferAgent_Completed(
            object sender,
            EventArgs e)
        {
            TransferAgent theInstance =
                sender as TransferAgent;

            Controller.AbortAndRemoveThread(theInstance);

            this._MainView.RemoveRow(theInstance);

            lock (this._LockObject)
            {
                --this._ActiveTransferCount;
            }

            this.UpdateStatusBar();

            if (this._MainView.Status.Equals(MainViewStatus.Started))
            {
                this.PlayAll();
            }
        }

        private void TransferAgent_Cancelled(
            object sender,
            EventArgs e)
        {
            TransferAgent theInstance =
                sender as TransferAgent;

            Controller.AbortAndRemoveThread(theInstance);

            lock (this._LockObject)
            {
                --this._ActiveTransferCount;
            }

            this.UpdateStatusBar();

            if (this._MainView.Status.Equals(MainViewStatus.Started))
            {
                this.PlayAll();
            }
        }

        private void TransferAgent_Failed(
            object sender,
            EventArgs e)
        {
            TransferAgent theInstance =
                sender as TransferAgent;

            Controller.AbortAndRemoveThread(theInstance);

            lock (this._LockObject)
            {
                --this._ActiveTransferCount;
            }

            this.UpdateStatusBar();

            if (this._MainView.Status.Equals(MainViewStatus.Started))
            {
                this.PlayAll();
            }
        }
        #endregion
        #endregion
    }
}
